package indexer;

import java.io.*;
import java.sql.*;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;

import utils.Constantes;

public class Indexer implements Runnable {
	private PreparedStatement documentInsertion = null;
	private PreparedStatement occurenceInsertion = null;
	private final String fileName;
	private final int idDocument;
	private Thread t;

	public Indexer(String fileName, int idDocument) {
		// Initialisation des variables
		this.fileName = fileName;
		this.idDocument = idDocument;
		
		// Préparation des statements
		try {
			Connection connection = Constantes.getConnetion();
			
			this.documentInsertion = connection.prepareStatement (
				"INSERT INTO document (id, nom, longueur) VALUES (?, ?, ?)"
			);

			this.occurenceInsertion = connection.prepareStatement (
				"INSERT INTO occurence (id_term, id_document, frequence) VALUES (?, ?, ?)"
			);
		} catch (ClassNotFoundException | SQLException ex) {
			Logger.getLogger(Indexer.class.getName()).log(Level.SEVERE, null, ex);
		}
	}
	
	/**
	 * fonction de lancement de l'indexation d'un document
	 */
	@Override
	public void run() {
		System.out.println("Lancement de l'indexation du document " + this.fileName);
		
		try {
			// Initialisation et parsing du document courant
			Document doc = new Document(this.fileName);
			doc.setIdBd(this.idDocument);
		
			// Insertion du document courant en base
			this.documentInsertion.setInt(1, doc.getIdBd());
			this.documentInsertion.setString(2, doc.getNom());
			this.documentInsertion.setInt(3, doc.getLongueur());
			this.documentInsertion.execute();

			// Insertion des occurences de termes du document courant
			for(Entry<Term, Integer> entry : doc.getFrequences().entrySet()) {
				Term terme = entry.getKey();
				Integer frequence = entry.getValue();

				try {
					this.occurenceInsertion.setInt(1, terme.getIdBd());
					this.occurenceInsertion.setInt(2, doc.getIdBd());
					this.occurenceInsertion.setInt(3, frequence);
					this.occurenceInsertion.execute();
				} catch (SQLException ex) {
					System.err.println("Erreur d'insertion en base de données du terme " + terme + ".");
					Logger.getLogger(Indexer.class.getName()).log(Level.SEVERE, null, ex);
				}
			}
		} catch (IOException e) {
			System.err.println("Erreur d'interprétation du fichier" + this.fileName + ".");
			Logger.getLogger(Indexer.class.getName()).log(Level.SEVERE, null, e);
		} catch (SQLException ex) {
			System.err.println("Erreur d'insertion du document " + this.fileName + " en base de données.");
			Logger.getLogger(Indexer.class.getName()).log(Level.SEVERE, null, ex);
		}
		
		System.out.println("## Fin de l'indexation du document " + this.fileName);
	}
	
	public void start() {
		if (t == null) {
			t = new Thread(this, this.fileName);
			t.start();
		}
	}
	
	public void join() throws InterruptedException {
		this.t.join();
	}
}
